﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using XiaoGang.Soft.XGWMS.COM;

namespace XiaoGang.Soft.XGWMS.UI
{
    public partial class BaseForm : Form
    {
        private ContextMenuStrip _captionMenuBar;
        public BaseForm()
        {
            this.SetStyle(
                ControlStyles.DoubleBuffer |
                ControlStyles.UserPaint |
                ControlStyles.ResizeRedraw |
                ControlStyles.OptimizedDoubleBuffer |
                ControlStyles.AllPaintingInWmPaint,
                true
            );

            this.UpdateStyles();
            InitializeComponent();

            InitAlphaAry();

            Load += new EventHandler(MainForm_Load);
        }

        void MainForm_Load(object sender, EventArgs e)
        {
        }

        private Rectangle oldRect = Rectangle.Empty;
        private Point oldMousePoint = new Point();
        private int Mode = -1;
        private Point m_MouseOffset =new Point();

        private List<CaptionControlButton> cBtns = new List<CaptionControlButton>();

        public static Cursor GetCursorForMode(int Mode)
        {
            switch (Mode)
            {
                case -1:
                    return Cursors.Default;
                case 0:
                    return Cursors.SizeAll;
                case 1:
                    return Cursors.SizeNWSE;
                case 2:
                    return Cursors.SizeNS;
                case 3:
                    return Cursors.SizeNESW;
                case 4:
                    return Cursors.SizeWE;
                case 5:
                    return Cursors.SizeNWSE;
                case 6:
                    return Cursors.SizeNS;
                case 7:
                    return Cursors.SizeNESW;
                case 8:
                    return Cursors.SizeWE;
            }
            return Cursors.Default;
        }

        private int HitTest(Point pt)
        {
            Rectangle rect = new Rectangle(
                FormStyleBorderWidth - 1,
                FormStyleBorderWidth - 1,
                Width - FormStyleBorderWidth * 2 - 2,
                FormStyleTitleHeight
            );

            if (rect.Contains(pt) == true)
            {
                return 0;
            }

            if (pt.X < FormStyleBorderWidth)
            {
                if (pt.Y < FormStyleBorderWidth)
                {
                    return 1;
                }
                else if (pt.Y > Height - FormStyleBorderWidth)
                {
                    return 7;
                }
                else
                {
                    return 8;
                }
            }

            if (pt.X > Width - FormStyleBorderWidth)
            {
                if (pt.Y < FormStyleBorderWidth)
                {
                    return 3;
                }
                else if (pt.Y > Height - FormStyleBorderWidth)
                {
                    return 5;
                }
                else
                {
                    return 4;
                }
            }
            if (pt.Y < FormStyleBorderWidth)
            {
                if (pt.X < FormStyleBorderWidth)
                {
                    return 1;
                }
                else if (pt.X > Width - FormStyleBorderWidth)
                {
                    return 3;
                }
                else
                {
                    return 2;
                }
            }
            if (pt.Y > Height - FormStyleBorderWidth)
            {
                if (pt.X < FormStyleBorderWidth)
                {
                    return 7;
                }
                else if (pt.X > Width - FormStyleBorderWidth)
                {
                    return 5;
                }
                else
                {
                    return 6;
                }
            }

            return -1;
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            Mode = HitTest(e.Location);
            oldRect = new Rectangle(Location, Size);
            oldMousePoint = Control.MousePosition;

            if (Mode != -1)
            {
                m_MouseOffset = new Point(-e.X, -e.Y);
            }
            else
            {

                base.OnMouseDown(e);
            }
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (Mode != -1)
            {
                Mode = -1;
            }
            else
            {
                base.OnMouseUp(e);
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (Mode == 0)
            {
                FormMove(e.Location);
            }
            else if (Mode >= 1 && Mode <= 8)
            {
                FormReSize();
            }
            else
            {
                Cursor = GetCursorForMode(HitTest(e.Location));
                base.OnMouseMove(e);
            }
        }

        private void FormReSize()
        {
            Rectangle rect = GetRectForMode(oldRect, oldMousePoint, Control.MousePosition, Mode);

            this.Bounds = rect;

        }
        
        private void FormMove(Point pt)
        {
            Point mousePos = new Point();
            mousePos = Control.MousePosition;
            mousePos.Offset(m_MouseOffset.X, m_MouseOffset.Y);
            Location = mousePos;
        }

        private Image _FormStyleCaptionImage = null;

        public Image FormStyleCaptionImage
        {
            get { return _FormStyleCaptionImage; }
            set { _FormStyleCaptionImage = value; }
        }

        private int _FormStyleTitleHeight = 20;

        public int FormStyleTitleHeight
        {
            get { return _FormStyleTitleHeight; }
            set {
                _FormStyleTitleHeight = value; 
                Refresh(); 
            }
        }

        private Color _FormStyleColor = Color.Red;

        public Color FormStyleColor
        {
            get { return _FormStyleColor; }
            set 
            {
                _FormStyleColor = value;
                Refresh();
            }
        }

        private Color _FormStyleCaptionColor = Color.Black;

        public Color FormStyleCaptionColor
        {
            get { return _FormStyleCaptionColor; }
            set 
            { 
                _FormStyleCaptionColor = value;
                Refresh();
            }
        }

        private int _FormStyleBorderWidth = 5;

        public int FormStyleBorderWidth
        {
            get { return _FormStyleBorderWidth; }
            set {
                if (value > 2)
                {
                    _FormStyleBorderWidth = value;
                }
                else
                {
                    _FormStyleBorderWidth = 2;
                }
                InitAlphaAry();
                Refresh(); 
            }
        }

        public ContextMenuStrip CaptionMenuBar 
        { 
            get{return _captionMenuBar;} 
            set{_captionMenuBar=value;} 
        }

        public int[] AlphaArray = new int[5];

        void DrawSytle(Graphics g)
        {
            Pen pen = null;

            DrawBorder(g, AlphaArray);

            DrawTitleBackGround(g, AlphaArray);

            

            Rectangle rectBack = new Rectangle(
                AlphaArray.Length,
                AlphaArray.Length / 2,
                FormStyleTitleHeight,
                FormStyleTitleHeight
            );

            int intTmp = (int)Math.Sqrt((FormStyleTitleHeight * FormStyleTitleHeight) / 2);

            Rectangle rectFore = new Rectangle(
                rectBack.X + (rectBack.Width - intTmp) / 2 + 1,
                rectBack.Y + (rectBack.Height - intTmp) / 2 + 1,
                intTmp,
                intTmp
            );


            g.SmoothingMode = SmoothingMode.HighQuality;

            pen = new Pen(Color.Silver, 2);

            //g.DrawRectangle(pen, rectBack);
            //g.DrawArc(Pens.Silver, rectBack, 0, 360);
            //g.DrawRectangle(Pens.Black, rectFore);

            g.SmoothingMode = SmoothingMode.None;
            
            DrawStyleColor(g, AlphaArray);

            DrawCaptionButton(g);

            if (FormStyleCaptionImage != null)
            {
                //g.DrawIcon(this.Icon, rectBack);
                g.DrawImage(FormStyleCaptionImage, rectBack);
            }

            Brush brush = new SolidBrush(FormStyleCaptionColor);

            string str = this.Text;

            Font f = new Font(FontFamily.GenericSansSerif, 8);
            SizeF size = g.MeasureString(str, f);

            g.DrawString(
                str, 
                f, 
                brush,
                FormStyleBorderWidth, 
                7
            );

            brush.Clone();


           
        }

        private void DrawCaptionButton(Graphics g)
        {
            g.DrawLine(
                Pens.Black,
                FormStyleBorderWidth,
                24,
                Width - FormStyleBorderWidth,
                24
            );
            g.DrawLine(
                Pens.Black,
                Width - FormStyleBorderWidth,
                0,
                Width - FormStyleBorderWidth,
                24
            );
            g.DrawLine(
                Pens.Silver,
                FormStyleBorderWidth,
                25,
                Width - FormStyleBorderWidth + 1,
                25
            );
            g.DrawLine(
                Pens.Silver,
                Width - FormStyleBorderWidth + 1,
                0,
                Width - FormStyleBorderWidth + 1,
                25
            );

        }
        
        private void InitAlphaAry()
        {
            AlphaArray = new int[FormStyleBorderWidth];
            Random rand = new Random();

            for (int i = 0; i < FormStyleBorderWidth - 1; i++)
            {
                AlphaArray[i] = 255 * i / (FormStyleBorderWidth + FormStyleTitleHeight);
                //alphaAry[i] = 255 - 255 * i / FormStyleBorderWidth;
                AlphaArray[i] = (255 / FormStyleBorderWidth) * i;
            }
            AlphaArray[FormStyleBorderWidth - 1] = 0;
        }

        private Pen DrawTitleBackGround(Graphics g, int[] alphaAry)
        {
            Pen pen = null;
            int sColor = alphaAry[alphaAry.Length - 3];
            int eColor = alphaAry[alphaAry.Length - 1];
            int cColor = 0;

            for (int i = 0; i < FormStyleTitleHeight; i++)
            {
                cColor = sColor + (eColor - sColor) * i / FormStyleTitleHeight;
                pen = new Pen(Color.FromArgb(cColor, cColor, cColor));

                g.DrawRectangle(
                    pen,
                    alphaAry.Length - 2 + i,
                    alphaAry.Length - 2 + i,
                    Width - (alphaAry.Length - 2 + i) * 2 - 1,
                    FormStyleTitleHeight - i
                );
                pen.Dispose();
            }
            return pen;
        }

        private void DrawBorder(Graphics g, int[] alphaAry)
        {
            Pen pen = null;

            for (int i = 0; i < alphaAry.Length - 1; i++)
            {
                pen = new Pen(Color.FromArgb(alphaAry[i], alphaAry[i], alphaAry[i]));

                g.DrawRectangle(pen, i, i, Width - 1 - i * 2, Height - 1 - i * 2);

                pen.Dispose();
            }

            pen = new Pen(Color.FromArgb(alphaAry[alphaAry.Length - 1], alphaAry[alphaAry.Length - 1], alphaAry[alphaAry.Length - 1]));
            g.DrawRectangle(
                pen,
                alphaAry.Length - 1,
                alphaAry.Length - 1 + FormStyleTitleHeight,
                Width - 1 - (alphaAry.Length - 1) * 2,
                Height - 1 - (alphaAry.Length - 1) * 2 - FormStyleTitleHeight
            );

            pen.Dispose();

        }

        private void DrawStyleColor(Graphics g, int[] alphaAry)
        {
            Color bc = Color.FromArgb(127, _FormStyleColor);
            Brush brush = new SolidBrush(bc);

            g.FillRectangle(
                brush,
                0,
                0,
                Width,
                FormStyleTitleHeight + alphaAry.Length
            );
            g.FillRectangle(
                brush,
                0,
                alphaAry.Length + FormStyleTitleHeight,
                alphaAry.Length,
                Height - FormStyleTitleHeight - alphaAry.Length * 2
            );
            g.FillRectangle(
                brush,
                Width - alphaAry.Length,
                alphaAry.Length + FormStyleTitleHeight,
                alphaAry.Length,
                Height - FormStyleTitleHeight - alphaAry.Length * 2
            );

            g.FillRectangle(
                brush,
                0,
                Height - alphaAry.Length,
                Width,
                FormStyleTitleHeight + alphaAry.Length
            );

            brush.Dispose();
        }

        public Size GetPointOffset(Point start, Point end)
        {
            return new Size(end.X - start.X, end.Y - start.Y);
        }

        public Rectangle GetRectForMode(Rectangle oldRect, Point s, Point e, int mode)
        {
            Rectangle rect = new Rectangle(oldRect.Location, oldRect.Size);
            Size offset = GetPointOffset(s, e);
            
            switch (mode)
            {
                case 0:
                    rect.X += offset.Width;
                    rect.Y += offset.Height;
                    break;
                case 1:
                    rect.X = Math.Min(rect.X + offset.Width, rect.Right - MinimumSize.Width);
                    rect.Y = Math.Min(rect.Y + offset.Height, rect.Bottom - MinimumSize.Height);
                    rect.Width = rect.Width - offset.Width;
                    rect.Height = rect.Height - offset.Height;
                    break;
                case 2:
                    rect.Y = Math.Min(rect.Y + offset.Height, rect.Bottom - MinimumSize.Height);
                    rect.Height = rect.Height - offset.Height;
                    break;
                case 3:
                    rect.Y = Math.Min(rect.Y + offset.Height, rect.Bottom - MinimumSize.Height);
                    rect.Width = rect.Width + offset.Width;
                    rect.Height = rect.Height - offset.Height;
                    break;
                case 4:
                    rect.Width = rect.Width + offset.Width;
                    break;
                case 5:
                    rect.Width = rect.Width + offset.Width;
                    rect.Height = rect.Height + offset.Height;
                    break;
                case 6:
                    rect.Height = rect.Height + offset.Height;
                    break;
                case 7:
                    rect.X = Math.Min(rect.X + offset.Width, rect.Right - MinimumSize.Width);
                    rect.Width = rect.Width - offset.Width;
                    rect.Height = rect.Height + offset.Height;
                    break;
                case 8:
                    rect.X = Math.Min(rect.X + offset.Width, rect.Right - MinimumSize.Width);
                    rect.Width = rect.Width - offset.Width;
                    break;
            }
            return rect;
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            base.OnPaintBackground(e);
            DrawSytle(e.Graphics);
        }

        private void BaseForm_Load(object sender, EventArgs e)
        {

        }

        protected override void OnDoubleClick(EventArgs e)
        {
            if (Mode == 0)
            {
                if (WindowState == FormWindowState.Maximized)
                {
                    WindowState = FormWindowState.Normal;
                }
                else
                {
                    WindowState = FormWindowState.Maximized;
                }
                
                this.Refresh();
            }
            base.OnDoubleClick(e);
        }

        public static void KeyPress(System.Windows.Forms.KeyPressEventArgs e, InputType emInputType)
        {
            int intChar = 0;
            intChar = e.KeyChar;
            switch (emInputType)
            {
                case InputType.Num:
                    if ((48 <= intChar && 57 >= intChar) || intChar == 8)
                    {
                        return;
                    }
                    break;
                case InputType.Dbl:
                    if ((48 <= intChar && intChar <= 57) || intChar == 8 || intChar == 46)
                    {
                        return;
                    }
                    break;
                case InputType.Tel:
                    if ((48 <= intChar && intChar <= 57) || intChar == 8 || intChar == 45)
                    {
                        return;
                    }
                    break;
                case InputType.Date:
                    if ((48 <= intChar && intChar <= 57) || intChar == 8 || intChar == 47)
                    {
                        return;
                    }
                    break;
                case InputType.AlphaAndNum:
                    if ((48 <= intChar && intChar <= 57) || (97 <= intChar && intChar <= 122) || (65 <= intChar && intChar <= 90) || intChar == 8)
                    {
                        return;
                    }
                    break;
                default:
                    break;
            }
            e.Handled = true;
        }

        protected virtual bool CheckProcess(string strConstrolName)
        {
            return true;
        }

        protected virtual void AllTextBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            string strControlname = ((System.Windows.Forms.Control)sender).Name;
            if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Down)
            {
                if (CheckProcess(strControlname))
                {
                    SendKeys.Send("{Tab}");
                }
                else
                {
                    return;
                }
            }
            else if (e.KeyCode == Keys.Up)
            {
                SendKeys.Send("+{Tab}");
            }
        }

        protected bool CheckProcess(string strValue, enumCheckItems enumItems, bool blnAllowEmpty, System.Windows.Forms.ComboBox combox)
        {
            switch (enumItems)
            {
                #region enumCheckItems.ItemID

                case enumCheckItems.ItemID:
                    if (!Method.CheckIsNumber(strValue, 12, blnAllowEmpty, true))
                    {
                        Method.MessageShow(GlobalVal.glostrMsg);
                        return false;
                    }
                    if (!blnAllowEmpty || strValue.Length != 0)
                    {
                        if (strValue.Length != 12)
                        {
                            Method.MessageShow("W11006");//The length is input Wrong!
                            return false;
                        }
                    }
                    break;

                #endregion

                #region enumCheckItems.USER_LOGIN_ID

                case enumCheckItems.USER_LOGIN_ID:
                    if (!Method.CheckIsHanAll(strValue, blnAllowEmpty, true))
                    {
                        Method.MessageShow(GlobalVal.glostrMsg);
                        return false;
                    }
                    if (!blnAllowEmpty || strValue.Length != 0)
                    {
                        if (strValue.Length > 50)
                        {
                            Method.MessageShow("W11006");//The length is input Wrong!
                            return false;
                        }
                    }
                    break;

                #endregion

                #region enumCheckItems.ItemName

                case enumCheckItems.ItemName:
                    if (!Method.CheckIsAllInputType(strValue, 25, blnAllowEmpty, true))
                    {
                        Method.MessageShow(GlobalVal.glostrMsg);
                        return false;
                    }
                    break;

                #endregion

                #region enumCheckItems.UserGroup
                case enumCheckItems.UserGroup:
                    if (!Method.CheckIsAllInputType(strValue, 50, blnAllowEmpty, true))
                    {
                        Method.MessageShow(GlobalVal.glostrMsg);
                        return false;
                    }
                    break;
                #endregion

                #region enumCheckItems.DateYMD

                case enumCheckItems.DateYMD:
                    if (!Method.CheckIsDate(strValue, blnAllowEmpty, true))
                    {
                        Method.MessageShow(GlobalVal.glostrMsg);
                        return false;
                    }
                    break;

                #endregion

                #region enumCheckItems.PHONE_NO
                case enumCheckItems.PHONE_NO:
                    if (!Method.CheckIsTelNo(strValue, blnAllowEmpty, true))
                    {
                        Method.MessageShow(GlobalVal.glostrMsg);
                        return false;
                    }
                    break;
                #endregion

                #region enumCheckItems.E_Mail
                case enumCheckItems.E_Mail:
                    if (!Method.CheckIsEmail(strValue, blnAllowEmpty, true))
                    {
                        Method.MessageShow(GlobalVal.glostrMsg);
                        return false;
                    }
                    break;
                #endregion

                #region enumCheckItems.Post
                case enumCheckItems.Post:
                    if (!Method.CheckIsNumber(strValue, 6, blnAllowEmpty, true))
                    {
                        Method.MessageShow(GlobalVal.glostrMsg);
                        return false;
                    }
                    break;
                #endregion

                #region enumCheckItems.ItemMEMO

                case enumCheckItems.ItemMEMO:
                    if (!Method.CheckIsAllInputType(strValue, 128, blnAllowEmpty, true))
                    {
                        Method.MessageShow(GlobalVal.glostrMsg);
                        return false;
                    }
                    break;

                #endregion

                default:
                    break;
            }
            return true;
        }
    }
}
